package net.realsee.service.wcs.work.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import net.realsee.common.utils.StringUtils;
import net.realsee.domain.wcs.work.WcsOrderDetail;
import net.realsee.domain.wcs.work.bo.WcsOrderDetailBo;
import net.realsee.domain.wcs.work.vo.WcsOrderDetailVo;
import net.realsee.framework.core.domain.PageQuery;
import net.realsee.framework.core.page.TableDataInfo;
import net.realsee.mapper.wcs.work.WcsOrderDetailMapper;
import net.realsee.service.wcs.work.IWcsOrderDetailService;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 单据行Service业务层处理
 *
 * @author realsee
 * @date 2023-08-11
 */
@RequiredArgsConstructor
@Service
public class WcsOrderDetailServiceImpl extends ServiceImpl<WcsOrderDetailMapper, WcsOrderDetail> implements IWcsOrderDetailService {

    private final WcsOrderDetailMapper baseMapper;

    /**
     * 查询单据行
     */
    @Override
    public WcsOrderDetailVo selectVoById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询单据行列表
     */
    @Override
    public TableDataInfo<WcsOrderDetailVo> selectVoPage(WcsOrderDetailBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<WcsOrderDetail> lqw = buildVoQueryWrapper(bo);
        Page<WcsOrderDetailVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询单据行列表
     */
    @Override
    public List<WcsOrderDetailVo> selectVoList(WcsOrderDetailBo bo) {
        LambdaQueryWrapper<WcsOrderDetail> lqw = buildVoQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<WcsOrderDetail> buildVoQueryWrapper(WcsOrderDetailBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<WcsOrderDetail> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getId() != null, WcsOrderDetail::getId, bo.getId());
        lqw.eq(StringUtils.isNotBlank(bo.getOrderNo()), WcsOrderDetail::getOrderNo, bo.getOrderNo());
        lqw.eq(bo.getOrderType() != null, WcsOrderDetail::getOrderType, bo.getOrderType());
        lqw.eq(StringUtils.isNotBlank(bo.getTaskType()), WcsOrderDetail::getTaskType, bo.getTaskType());
        lqw.eq(bo.getOrderLineNo() != null, WcsOrderDetail::getOrderLineNo, bo.getOrderLineNo());
        lqw.eq(StringUtils.isNotBlank(bo.getSubOrderNo()), WcsOrderDetail::getSubOrderNo, bo.getSubOrderNo());
        lqw.eq(StringUtils.isNotBlank(bo.getSourceSubTaskCode()), WcsOrderDetail::getSourceSubTaskCode, bo.getSourceSubTaskCode());
        lqw.eq(StringUtils.isNotBlank(bo.getStepCompCode()), WcsOrderDetail::getStepCompCode, bo.getStepCompCode());
        lqw.eq(StringUtils.isNotBlank(bo.getStepCode()), WcsOrderDetail::getStepCode, bo.getStepCode());
        lqw.like(StringUtils.isNotBlank(bo.getStepName()), WcsOrderDetail::getStepName, bo.getStepName());
        lqw.eq(StringUtils.isNotBlank(bo.getWipLineNo()), WcsOrderDetail::getWipLineNo, bo.getWipLineNo());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNo()), WcsOrderDetail::getProductNo, bo.getProductNo());
        lqw.eq(bo.getQuantity() != null, WcsOrderDetail::getQuantity, bo.getQuantity());
        lqw.eq(StringUtils.isNotBlank(bo.getUomCode()), WcsOrderDetail::getUomCode, bo.getUomCode());
        lqw.eq(StringUtils.isNotBlank(bo.getContainer()), WcsOrderDetail::getContainer, bo.getContainer());
        lqw.eq(StringUtils.isNotBlank(bo.getFromWarehouse()), WcsOrderDetail::getFromWarehouse, bo.getFromWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getFromLocation()), WcsOrderDetail::getFromLocation, bo.getFromLocation());
        lqw.eq(StringUtils.isNotBlank(bo.getFromBin()), WcsOrderDetail::getFromBin, bo.getFromBin());
        lqw.eq(StringUtils.isNotBlank(bo.getToWarehouse()), WcsOrderDetail::getToWarehouse, bo.getToWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getToLocation()), WcsOrderDetail::getToLocation, bo.getToLocation());
        lqw.eq(StringUtils.isNotBlank(bo.getToBin()), WcsOrderDetail::getToBin, bo.getToBin());
        lqw.eq(StringUtils.isNotBlank(bo.getFinalToWarehouse()), WcsOrderDetail::getFinalToWarehouse, bo.getFinalToWarehouse());
        lqw.eq(StringUtils.isNotBlank(bo.getFinalToLocation()), WcsOrderDetail::getFinalToLocation, bo.getFinalToLocation());
        lqw.eq(StringUtils.isNotBlank(bo.getFinalToBin()), WcsOrderDetail::getFinalToBin, bo.getFinalToBin());
        lqw.eq(bo.getProgressStatus() != null, WcsOrderDetail::getProgressStatus, bo.getProgressStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getOutputStationLocation()), WcsOrderDetail::getOutputStationLocation, bo.getOutputStationLocation());
        lqw.eq(StringUtils.isNotBlank(bo.getInputStationLocation()), WcsOrderDetail::getInputStationLocation, bo.getInputStationLocation());
        lqw.eq(bo.getStartTime() != null, WcsOrderDetail::getStartTime, bo.getStartTime());
        lqw.eq(bo.getCompletionTime() != null, WcsOrderDetail::getCompletionTime, bo.getCompletionTime());
        lqw.eq(StringUtils.isNotBlank(bo.getMap()), WcsOrderDetail::getMap, bo.getMap());
        lqw.eq(StringUtils.isNotBlank(bo.getMapMark()), WcsOrderDetail::getMapMark, bo.getMapMark());
        lqw.eq(StringUtils.isNotBlank(bo.getFixPositionRef()), WcsOrderDetail::getFixPositionRef, bo.getFixPositionRef());
        lqw.eq(StringUtils.isNotBlank(bo.getPosOffset()), WcsOrderDetail::getPosOffset, bo.getPosOffset());
        lqw.eq(StringUtils.isNotBlank(bo.getVehicleLocation()), WcsOrderDetail::getVehicleLocation, bo.getVehicleLocation());
        lqw.eq(StringUtils.isNotBlank(bo.getMessage()), WcsOrderDetail::getMessage, bo.getMessage());
        lqw.eq(StringUtils.isNotBlank(bo.getInterfaceTaskId()), WcsOrderDetail::getInterfaceTaskId, bo.getInterfaceTaskId());
        lqw.eq(StringUtils.isNotBlank(bo.getOperationCode()), WcsOrderDetail::getOperationCode, bo.getOperationCode());
        lqw.eq(StringUtils.isNotBlank(bo.getInterfaceFlag()), WcsOrderDetail::getInterfaceFlag, bo.getInterfaceFlag());
        lqw.eq(StringUtils.isNotBlank(bo.getExternalTaskId()), WcsOrderDetail::getExternalTaskId, bo.getExternalTaskId());
        lqw.eq(StringUtils.isNotBlank(bo.getExternalTaskStatus()), WcsOrderDetail::getExternalTaskStatus, bo.getExternalTaskStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getInlineInputs()), WcsOrderDetail::getInlineInputs, bo.getInlineInputs());
        lqw.eq(StringUtils.isNotBlank(bo.getInlineOutputs()), WcsOrderDetail::getInlineOutputs, bo.getInlineOutputs());
        lqw.eq(StringUtils.isNotBlank(bo.getCallCode()), WcsOrderDetail::getCallCode, bo.getCallCode());
        lqw.eq(StringUtils.isNotBlank(bo.getPodCode()), WcsOrderDetail::getPodCode, bo.getPodCode());
        lqw.eq(StringUtils.isNotBlank(bo.getPodDir()), WcsOrderDetail::getPodDir, bo.getPodDir());
        lqw.eq(StringUtils.isNotBlank(bo.getCtnrCode()), WcsOrderDetail::getCtnrCode, bo.getCtnrCode());
        lqw.eq(StringUtils.isNotBlank(bo.getCtnrType()), WcsOrderDetail::getCtnrType, bo.getCtnrType());
        lqw.eq(StringUtils.isNotBlank(bo.getWbCode()), WcsOrderDetail::getWbCode, bo.getWbCode());
        lqw.eq(StringUtils.isNotBlank(bo.getCurrentPositionCode()), WcsOrderDetail::getCurrentPositionCode, bo.getCurrentPositionCode());
        lqw.eq(StringUtils.isNotBlank(bo.getMapDataCode()), WcsOrderDetail::getMapDataCode, bo.getMapDataCode());
        lqw.eq(StringUtils.isNotBlank(bo.getMethod()), WcsOrderDetail::getMethod, bo.getMethod());
        lqw.eq(StringUtils.isNotBlank(bo.getRobotCode()), WcsOrderDetail::getRobotCode, bo.getRobotCode());
        lqw.eq(StringUtils.isNotBlank(bo.getFuid()), WcsOrderDetail::getFuid, bo.getFuid());
        lqw.eq(bo.getTextId() != null, WcsOrderDetail::getTextId, bo.getTextId());
        lqw.eq(bo.getRefrenceId() != null, WcsOrderDetail::getRefrenceId, bo.getRefrenceId());
        lqw.eq(bo.getUnitId() != null, WcsOrderDetail::getUnitId, bo.getUnitId());
        lqw.eq(bo.getDelFlag() != null, WcsOrderDetail::getDelFlag, bo.getDelFlag());
        lqw.eq(StringUtils.isNotBlank(bo.getCreateBy()), WcsOrderDetail::getCreateBy, bo.getCreateBy());
        lqw.eq(bo.getCreateTime() != null, WcsOrderDetail::getCreateTime, bo.getCreateTime());
        lqw.eq(StringUtils.isNotBlank(bo.getUpdateBy()), WcsOrderDetail::getUpdateBy, bo.getUpdateBy());
        lqw.eq(bo.getUpdateTime() != null, WcsOrderDetail::getUpdateTime, bo.getUpdateTime());
        lqw.eq(StringUtils.isNotBlank(bo.getDeleteBy()), WcsOrderDetail::getDeleteBy, bo.getDeleteBy());
        lqw.eq(bo.getDeleteTime() != null, WcsOrderDetail::getDeleteTime, bo.getDeleteTime());
        lqw.eq(bo.getRowVersionStamp() != null, WcsOrderDetail::getRowVersionStamp, bo.getRowVersionStamp());
        lqw.eq(StringUtils.isNotBlank(bo.getRemark()), WcsOrderDetail::getRemark, bo.getRemark());
        lqw.orderByDesc(WcsOrderDetail::getId);
        return lqw;
    }

    /**
     * 新增单据行
     */
    @Override
    public Boolean insertByBo(WcsOrderDetailBo bo) {
        WcsOrderDetail add = BeanUtil.toBean(bo, WcsOrderDetail.class);
        return this.save(add);
    }

    /**
     * 修改单据行
     */
    @Override
    public Boolean updateByBo(WcsOrderDetailBo bo) {
        WcsOrderDetail update = BeanUtil.toBean(bo, WcsOrderDetail.class);
        return this.updateById(update);
    }

    /**
     * 批量删除单据行
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids) {
        return this.removeBatchByIds(ids);
    }

    /**
     * 通过订单号和订单类型和目的库位查询
     */
    @Override
    public WcsOrderDetail getByOrderNoAndOrderTypeAndToLocation(String orderNo, Long orderType, String toLocation) {
        return this.lambdaQuery()
            .eq(WcsOrderDetail::getOrderNo, orderNo)
            .eq(WcsOrderDetail::getOrderType, orderType)
            .eq(WcsOrderDetail::getToLocation, toLocation)
            .last("limit 1")
            .one();
    }

    @Override
    public String getEndLocationByOrderNoAndOrderType(String orderNo, Long orderType) {
        WcsOrderDetail detail = this.lambdaQuery()
            .eq(WcsOrderDetail::getOrderNo, orderNo)
            .eq(WcsOrderDetail::getOrderType, orderType)
            .orderByDesc(WcsOrderDetail::getId)
            .last("limit 1")
            .one();
        return ObjectUtil.isNull(detail) ? StrUtil.EMPTY : detail.getToLocation();
    }
}
